package com.ztl.leetcode.SwordFingerOffer;

import java.util.Arrays;

/**
 * @author @ztl
 * @ClassName:StringToNumber
 * @Package:com.ztl.leetcode.SwordFingerOffer
 * @date 2023年05月12日 20:40
 * @description: 写一个函数 StrToInt，实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。
 * @version: 1.0
 */
public class StringToNumber_67 {

    //仅需遍历一次字符串，事件复杂度O(n),使用字符数字存储临时数据空间复杂度O(n)
    public int strToInt(String str) {
        //需要先去除首尾空格，再判断str长度
        //反过来则有可能出"   "的情况导致意外的结果
        str = str.trim();
        if(str.length() == 0){
            return 0;
        }
        //可以转换的字符串首尾只有3种情况：'+' '-' '0~9'
        //先对首位进行判断，使用'isMinus'记录首位是否为'-'号，方便最后进行计算
        boolean isMinus = false;

        //将字符串转换成字符数组方便循环判断
        char[] ch = str.toCharArray();

        if(ch[0] == '+' || ch[0] == '-' || Character.isDigit(ch[0])){

            //判断首位是否为'+'或'-' ，如果是则需要把首位删除
            if(ch[0] == '+' || ch[0] == '-'){
                //判断首位是否为'-'号
                if(ch[0] == '-'){
                    isMinus = true;
                }
                //删除首位
                ch = Arrays.copyOfRange(ch,1,ch.length);
            }

            //使用index记录当前判断的下标，初始为0
            int index = 0;

            //使用long类型记录最终结果，防止结果超出int的最大值而导致溢出
            long res = 0;

            //循环遍历每个字符是否为数字
            while(index < ch.length && Character.isDigit(ch[index])){
                //每添加一位数字都需要将之前的res*10，再加上当前值
                //例如："12" = 1*10 + 2
                res *= 10;
                res += ch[index] - '0'; //char与int计算自动将结果转换为int

                //当前值大于int最大值时应该直接返回最大值
                if(res > Integer.MAX_VALUE){
                    //记得判断首位是否为'-'号
                    return isMinus ? Integer.MIN_VALUE : Integer.MAX_VALUE;
                }
                //循环控制
                index++;
            }
            //执行到这里代表数字字符串已经遍历完成且没有超过int最大值
            //直接将long强转为int
            return isMinus ? -(int)res : (int)res;
        }

        //首位非法字符，直接返回0
        return 0;
    }
}
